<?php
/**
 * 渝欧链多多供应商JDK
 * @author huj
 */

namespace App\Service\VendorClient\ShopyuouApi;

use App\Model\PssModel\ServiceConfig;
use App\Service\Code\Normal;
use App\Service\BaseService;
use Service\AppService\IdService;
use App\Service\TaskServer\TaskWorker;

class ShopyuouldoApiClient extends BaseService {

    private $config = [];

    public function __construct($apiBody = []) {
        $this->config = $apiBody;
    }

    /**
     * 创建订单
     * @param array $params
     * @return mixed
     */
    public function createOrder($param = []) {
        $orderInfo   = $param['supplierOrder'];//order_supplier表信息
        $goodsList   = $param['orderGoods'];//order_supplier_goods表信息
        $order       = $param['order'];//微服务请求时提交的数据
        $binfo       = $param['binfo'];//服务器信息
        $companyInfo = $param['companyInfo'];//供应商信息
        $order_sn    = $orderInfo['supplier_dsn'];//对外的订单号
        //支付流水号
        $pay_sn = $order['paySerial'] ?? $orderInfo['pay_sn'];
        //订单时间
        $order_time = $orderInfo['cd'] ? date('Y-m-d H:i:s', $orderInfo['cd']) : date('Y-m-d H:i:s', time());
        //支付时间
        $pay_time = isset($order['payTime']) && !empty($order['payTime']) ? date('Y-m-d H:i:s', $order['payTime']) : date('Y-m-d H:i:s', time());
        //判断支付方式是否存在
        $apply_extends  = @json_decode($orderInfo['apply_extends'], true);
        $payCommanyCode = $apply_extends['payCommanyCode'] ?? '';
        $queryCode      = $order['payCommanyCode'] ? $order['payCommanyCode'] : $payCommanyCode;
        $pay_value      = ServiceConfig::instance()->getConfigByEventsValue('shopyuouldo', ServiceConfig::TYPE_PAY, $queryCode);
        if (empty($pay_value)) {
            return Normal::returnCode(Normal::FAIL, "支付公司编码：【{$queryCode}】未映射，请联系管理员处理");
        }

        //运费分摊
        $deliver_money = $orderInfo['deliver_money'];
        //获取下单商品信息
        $palceOrderGoods = [];
        $goods_all_money = 0;
        foreach ($goodsList as $key => $item) {
            //卖价
            $price = $item['price'];
            //商品购买规格数量
            $spec_num = $item['spec_num'];
            //商品购买数量(下单数量 X 起售数量)
            $quantity = $item['quantity'];
            //实际购买数量
            $buyAcount = $spec_num * $quantity;

            //计算商品税前商品总金额公式应为：
            //custom_price  * qty + shipping_fee - discount

            //假设商品的综合税率为 r，那么商品的实际支付(报关)金额应为：
            //（custom_price  * qty + shipping_fee - discount）* r + custom_price  * qty + shipping_fee - discount - bonus_money

            //C端消费下单商品金额
            // $goods_all_money = bcadd((string)$goods_all_money, bcmul((string)$price, (string)$quantity, 2), 2);

            //商品税率
            $tax      = $item['tax_rate'];
            $tax_rate = bcadd((string)$tax, '1.0000', 4);

            //商品+税费
            $shipping_fee        = $key == 0 ? $deliver_money : 0;
            $single_shipping_fee = bcdiv((string)$shipping_fee, (string)$quantity, 3);
            $single_shipping_fee = ceil((float)$single_shipping_fee * 100) / 100;
            $price               = bcadd((string)$price, (string)$single_shipping_fee, 2);
            //商品包邮含税总金额
            $goodsMoney = bcmul((string)$price, (string)$quantity, 2);

            //获取商品不含税价格 ,小数第三位收了之后再进行合计计算
            $goods_price = bcdiv((string)$goodsMoney, (string)$tax_rate, 3);
            $goods_price = bcdiv((string)$goods_price, (string)$buyAcount, 3);
            //包邮不含税单价
            $singleGoodsPrice = ceil((float)$goods_price * 100) / 100;
            //包邮不含税总金额
            $singleGoodsSummaryMoney = bcmul((string)$singleGoodsPrice, (string)$buyAcount, 2);

            //税金
            $summaryTaxAmt     = bcsub((string)$goodsMoney, (string)$singleGoodsSummaryMoney, 2);
            $summaryGoodsMoney = bcadd((string)$summaryTaxAmt, (string)$singleGoodsSummaryMoney, 2);
            //金额差异 放在优惠金额
            $sub_goods_money = bcsub((string)$goodsMoney, (string)$summaryGoodsMoney, 2);
            //单个商品总金额
            $goods_all_money = bcadd((string)$goods_all_money, $goodsMoney, 2);
            //下单商品组  商品单价*商品购买数量+商品运费+商品关税+商品消费税+商品增值税-计税折扣-不计税折扣
            $palceOrderGoods[] = [
                'salePlatGoodsSn' => trim($item['skucode']),//商户系统商品编码
                'supplierGoodsSn' => trim($item['supplier_skucode']),//全球云链商品编码
                'goodsName'       => trim($item['goods_name']),//商品的实际名称
                'spec'            => $spec_num,//商品规格（举例：6罐装的奶粉，规格为6）
                'specQty'         => $quantity,//商品规格购买数量（购买的组合装件数）; 实际购买数量 = 商品规格购买数量 * 商品规格
                'qty'             => $buyAcount,//商品的总购买数量，若商品规格和商品规格数量传值，则商品购买数量=商品规格*商品规格数量
                'price'           => $singleGoodsPrice,//商品不含税单价，单位为元，保留两位小数
                'shipFee'         => 0,//商品分摊的运费，若为包邮商品则为0
                'discountNeedTax' => 0,//商品分摊的需要计税的商品优惠金额，通常为优惠券
                'discountTaxFree' => $sub_goods_money,//商品分摊的不需要计税的商品优惠金额，通常为活动折扣
                'customsTax'      => 0,//商品分摊的关税，若为保税订单则为0
                'saleTax'         => $summaryTaxAmt,//商品分摊的消费税，若商品为高税产品，需传该值
                'addedValueTax'   => 0,//商品分摊的增值税
                'isGift'          => false,//商品是否赠品，若为保税订单，不支持订单中包含赠品，枚举值：true：是false：否
                // 'goodsAmount'     => $singleGoodsSummaryMoney,//商品成交总金额; 商品成交总金额 = 商品成交单价 * 商品规格购买数量 * 商品规格
            ];
        }
        //商品类型
        $goods_type = current($goodsList)['goods_type']; // 现有商品类型（0-一般贸易，1-保税商品，2-海外直邮, 3海外购）
        $goods_type = $goods_type == 3 ? 2 : $goods_type;

        //订单总金额 = 商品金额 + 运费
        // $orderTotalMoney  = bcadd((string)$goods_all_money, (string)$deliver_money, 2);
        $real_total_money = $orderInfo['real_total_money'];
        $bc_sub_money     = bcsub((string)$goods_all_money, (string)$real_total_money, 2);
        //如果计算有差异
        if ($bc_sub_money > 0) {
            foreach ($palceOrderGoods as $key => & $goods) {
                if ($key == 0) {
                    $goods['discountTaxFree'] = $bc_sub_money;
                }
            }
        }

        $requestParam = [
            'platformCode'   => $this->config['platformCode'],//商户在全球云链入驻后，由API生成的平台编码，全局唯一
            'shopName'       => $this->config['shopName'],//商户开通API服务后，由平台运营人员分配的平台店铺标识
            'salePlfOrderSn' => $order_sn,//商户系统内部订单号
            'tradeModeCode'  => (string)$goods_type,//订单贸易模式，枚举值0：一般贸易1：保税贸易2：快件直邮
            'consignee'      => $orderInfo['receive_name'],//订单收货人姓名
            'phone'          => $orderInfo['recveive_phone'],//收货人电话号码
            'provinceName'   => $orderInfo['province'],//收货省份名称
            'cityName'       => $orderInfo['city'],//收货城市名称
            'districtName'   => $orderInfo['district'],//收货地区名称
            'detailAddress'  => $orderInfo['receive_address'],//详细收货地址
            'buyerName'      => $orderInfo['buyer_realname'],//订购人姓名
            'buyerIdentity'  => $orderInfo['buyer_idcard'],//订购人身份证号码
            'customsOrderSn' => $order_sn,//商户报关的订单号，保税贸易必传
            'paymentCode'    => $pay_value,//订单支付公司编码，支付公司与编码对应关系见附录
            // 'paymentCode'    => '01',//测试环境 只能用这个
            'payOrderSn'     => $order_sn,//商户报关的支付单号
            'payTransSn'     => $pay_sn,//支付流水号
            'payTime'        => $pay_time,//用户在商户系统的实际付款时间，格式为yyyy-MM-DD HH:mm:ss
            'orderTime'      => $order_time,//商户系统订单创建时间，格式为yyyy-MM-DD HH:mm:ss
            'payAmount'      => $real_total_money,//订单实际支付金额，单位为元，保留两位小数；支付金额=订单总金额=∑商品单价*商品购买数量+商品运费+商品关税+商品消费税+商品增值税-计税折扣-不计税折扣
            'eCommerceCode'  => $order['enterpriseNum'],//商户电商平台在海关的十位备案编码
            'eCommerceName'  => $order['enterpriseName'],//商户电商平台在海关的备案名称
            'goodsList'      => $palceOrderGoods,//订单包含的商品列表
        ];

        $data = [
            'method' => 'createOrder',
            'data'   => $requestParam,
        ];
        return $this->execute($data);
    }

    /**
     * 签名
     * @param $data
     * @param $commonData
     * @return string
     */
    public function sign($data, $commonData) {
        $arrTmp = [];
        foreach ($commonData as $k => $v) {
            //参数为空不参与签名
            if (isset($v) && $v != '') {
                array_push($arrTmp, $k . $v);
            }
        }
        $stringA = implode('', $arrTmp);
        $stringB = json_encode($data);
        $stringC = $stringA . $stringB . $this->config['appSecret'];
        $stringD = md5($stringC);
        return strtoupper($stringD);
    }

    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    public function execute($param = []) {
        $method = $param['method'];
        $data   = $param['data'];
        if (empty($this->config['baseUrl'])) {
            return Normal::returnCode(Normal::FAIL, "当前仓库参数baseurl未配置");
        }

        if (empty($this->config[$method])) {
            return Normal::returnCode(Normal::FAIL, "当前仓库参数【{$method}】未配置");
        }
        $baseUrl            = $this->config['baseUrl'];
        $applyUrl           = $this->config['baseUrl'] . $this->config[$method];
        $commonData         = [
            'appkey'    => $this->config['appKey'],
            'nonce'     => uuid4(),
            'timestamp' => time(),
        ];
        $pushData           = $data;
        $commonData['sign'] = $this->sign($data, $commonData);
        $parameter          = [
            [
                'tag'    => 'shopyuouldo_' . $method,
                'uid'    => IdService::instance()->getOtherID(),
                'url'    => $applyUrl,
                'data'   => $pushData,
                'method' => 'post',
                'format' => 'json',
                'header' => [
                    "Content-Type: application/json",
                    "appkey: {$commonData['appkey']}",
                    "nonce: {$commonData['nonce']}",
                    "timestamp: {$commonData['timestamp']}",
                    "sign: {$commonData['sign']}",
                ],
            ],
        ];
        $resTask            = TaskWorker::instance()->addTask($parameter);
        $resTask            = current($resTask);
        $result             = @json_decode($resTask['response']['result'], true);
        if (isset($result['code']) && $result['code'] == Normal::SUC) {
            if (isset($result['success']) && $result['success'] == true) {
                return Normal::returnCode(Normal::SUC, "请求成功", $result);
                // return Normal::returnCode(Normal::SUC, "OK", [
                //     'thirdpart_order_sn' => $result['data']['mainOrderSn']
                // ]);
            }
        }
        return Normal::returnCode(Normal::FAIL, $result['message'] ?? '请求失败');
    }
}